﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;

namespace WPFSample.ExamineRoutedEventsSample
{
    class ExamineRoutedEvents : Window
    {
        static readonly FontFamily fontfam = new FontFamily("Lucida Console");
        const string strFormat = "{0,-30} {1,-20} {2,-20} {3,-15}";
        StackPanel stackOutput;
        DateTime dtLast;

        public ExamineRoutedEvents()
        {
            this.Title = "Examine Routed Events";

            Grid grid = new Grid();
            this.Content = grid;

            RowDefinition rowdef = new RowDefinition();
            rowdef.Height = GridLength.Auto;
            grid.RowDefinitions.Add(rowdef);

            rowdef = new RowDefinition();
            rowdef.Height = GridLength.Auto;
            grid.RowDefinitions.Add(rowdef);

            rowdef = new RowDefinition();
            rowdef.Height = new GridLength(100, GridUnitType.Star);
            grid.RowDefinitions.Add(rowdef);

            Button btn = new Button();
            btn.HorizontalAlignment = HorizontalAlignment.Center;
            btn.Margin = new Thickness(24);
            btn.Padding = new Thickness(24);
            grid.Children.Add(btn);

            TextBlock text = new TextBlock();
            text.FontSize = 24;
            text.Text = this.Title;
            btn.Content = text;

            TextBlock textHeadings = new TextBlock();
            textHeadings.FontFamily = fontfam;
            textHeadings.Inlines.Add(new Underline(new Run(
                string.Format(strFormat, "Routed Event", "Sender", "Source", "OriginalSource"))));
            grid.Children.Add(textHeadings);
            Grid.SetRow(textHeadings, 1);

            ScrollViewer scroll = new ScrollViewer();
            grid.Children.Add(scroll);
            Grid.SetRow(scroll, 2);

            stackOutput = new StackPanel();
            scroll.Content = stackOutput;

            UIElement[] els = { this, grid, btn, text };

            foreach (var el in els)
            {
                el.PreviewKeyDown += this.AllPurposeEventHandler;
                el.PreviewKeyUp += this.AllPurposeEventHandler;
                el.KeyDown += this.AllPurposeEventHandler;
                el.KeyUp += this.AllPurposeEventHandler;
                el.TextInput += this.AllPurposeEventHandler;

                el.MouseDown += this.AllPurposeEventHandler;
                el.MouseUp += this.AllPurposeEventHandler;
                el.PreviewMouseDown += this.AllPurposeEventHandler;
                el.PreviewMouseUp += this.AllPurposeEventHandler;

                //el.MouseLeftButtonDown += this.AllPurposeEventHandler;
                //el.MouseLeftButtonUp += this.AllPurposeEventHandler;
                //el.PreviewMouseLeftButtonDown += this.AllPurposeEventHandler;
                //el.PreviewMouseLeftButtonUp += this.AllPurposeEventHandler;

                el.MouseRightButtonDown += this.AllPurposeEventHandler;
                el.MouseRightButtonUp += this.AllPurposeEventHandler;
                el.PreviewMouseRightButtonDown += this.AllPurposeEventHandler;
                el.PreviewMouseRightButtonUp += this.AllPurposeEventHandler;

                //el.StylusDown += this.AllPurposeEventHandler;
                //el.StylusUp += this.AllPurposeEventHandler;
                //el.PreviewStylusDown += this.AllPurposeEventHandler;
                //el.PreviewStylusUp += this.AllPurposeEventHandler;

                el.TouchDown += this.AllPurposeEventHandler;
                el.TouchUp += this.AllPurposeEventHandler;
                el.PreviewTouchDown += this.AllPurposeEventHandler;
                el.PreviewTouchUp += this.AllPurposeEventHandler;

                el.AddHandler(Button.ClickEvent, new RoutedEventHandler(this.AllPurposeEventHandler));
            }
        }

        private void AllPurposeEventHandler(object sender, RoutedEventArgs e)
        {
            DateTime dtNow = DateTime.Now;
            if (dtNow - this.dtLast > TimeSpan.FromMilliseconds(100))
            {
                stackOutput.Children.Add(new TextBlock(new Run(" ")));
            }

            this.dtLast = dtNow;

            TextBlock text = new TextBlock();
            text.FontFamily = fontfam;
            text.Text = string.Format(strFormat,
                e.RoutedEvent.Name,
                TypeWithoutNamespace(sender),
                TypeWithoutNamespace(e.Source),
                TypeWithoutNamespace(e.OriginalSource));
            stackOutput.Children.Add(text);
            (stackOutput.Parent as ScrollViewer).ScrollToBottom();
        }

        private string TypeWithoutNamespace(object sender)
        {
            string[] astr = sender.GetType().ToString().Split('.');
            return astr[astr.Length - 1];
        }
    }
}
